package j.framework.base.service.impl;

import j.framework.base.service.GeneralService;
import j.framework.core.EntityTrigger;
import j.framework.core.ServiceException;
import j.framework.core.ServiceContext;
import j.framework.domain.BaseDomain;
import j.util.New;
import j.util.StringUtils;
import j.util.jdbc.TransactionalJdbcTemplate;
import j.util.jdbc.simple.annotation.Table;
import j.util.pkgenerator.PG;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;

import java.util.Date;
import java.util.Map;

/**
 * User: jason
 * Date: 2014/11/10 16:42
 */
public class GeneralServiceImpl implements GeneralService {
    private static final Log log = LogFactory.getLog(GeneralServiceImpl.class);
    @Override
    public Object findEntity(ServiceContext context,Object entity) {
        Table table = entity.getClass().getAnnotation(Table.class);
        BaseDomain bd = (BaseDomain)entity;
        Map<String,Object> args = New.map();
        args.put(table.pkColumns(),bd.getId());
        return context.getJdbcTemplate().findByPk(entity.getClass(), args);
    }

    @Override
    public void doSave(ServiceContext context,String pkTblKey,Object entity, EntityTrigger trigger) {
        String entityDsc = entity.toString();
        BaseDomain bd = (BaseDomain)entity;
        boolean isInsert = StringUtils.isNullOrEmpty(bd.getId());
        log.debug("通用业务层开始处理保存操作["+(isInsert?"增加":"修改")+"]，实体对象："+entityDsc);
        //触发器执行
        if(trigger!=null){
            if(isInsert){
                log.debug("调用增加前触发器...");
                if(!trigger.insertForBefore(context,bd)){
                    //触发器返回了false，则不再执行增加操作
                    log.debug("执行增加操作时，增加前触发器返回了false，不再执行以下序列的操作了。");
                    return;
                }
            }else{
                //这是修改操作
                log.debug("调用修改前触发器...");
                if(!trigger.updateForBefore(context,bd)){
                    //修改执行前触发器返回了false，则不再执行修改操作
                    log.debug("执行修改操作时，修改前触发器返回了false，不再执行以下序列的操作了。");
                    return;
                }
            }
        }
        TransactionalJdbcTemplate tjt = context.getTransactionalJdbcTemplate();
        //触发器前执行完毕
        //根据增加还是修改来保存实体类
        if(isInsert){
            //增加操作，获取主键
            bd.setId(PG.getNext(pkTblKey));
            bd.setAddedUserId(context.getUser().getUserId());
            bd.setAddedTime(new Date());
            int ret = 0;
            try{
                ret = tjt.insert(entity);
            }catch (Exception e){
                e.printStackTrace();
            }
            if(ret > 0) {
                context.getLog().setOperateType("增加");
                context.getLog().setLogContent(String.format("增加新实体%s", entityDsc));
                log.debug(context.getLog().getLogContent());
            }else if(ret == 0){
                context.actionResult.add("err","增加失败，请检测数据的完整性！");
            }else{
                context.actionResult.add("err","数据重复，请检查数据！");
            }
        }else{
            //修改保存
            int ret = tjt.update(entity);
            if(ret > 0) {
                context.getLog().setOperateType("修改");
                context.getLog().setLogContent(String.format("修改实体%s", entityDsc));
                log.debug(context.getLog().getLogContent());
            }else if(ret == 0){
                context.actionResult.add("err","修改失败，请检测数据的完整性！");
            }else{
                context.actionResult.add("err","数据重复，请检查数据！");
            }
        }
        //检测是否记录日志
        if(context.isLogSupported()){
            //需要记录日志
            log.debug("记录日志"+entityDsc);

        }else{
            log.debug("不需要记录日志");
        }
    }

    @Override
    public void doDelete(ServiceContext context,Object entity, EntityTrigger trigger) {
        BaseDomain bd = (BaseDomain)entity;
        log.debug("通用业务层开始处理删除操作，删除的实体对象ID："+bd.getId());
        //触发器执行
        if(trigger!=null){
            log.debug("调用删除前触发器...");
            if(!trigger.insertForBefore(context,bd)){
                //触发器返回了false，则不再执行增加操作
                log.debug("执行删除实体操作时，删除前触发器返回了false，不再执行以下序列的操作了。");
                return;
            }
        }
        TransactionalJdbcTemplate tjt = context.getTransactionalJdbcTemplate();
        //先从数据库中找到要删除的实体
        Object dbEntity = findEntity(context,entity);
        if(dbEntity==null){
            throw new ServiceException("ID为["+bd.getId()+"]不存在，请确认！");
        }
        tjt.delete(dbEntity);
        String entityDsc = dbEntity.toString();
        log.debug("删除了实体，实体内容："+entityDsc);
        if(context.isLogSupported()){
            //需要记录日志
            log.debug("记录日志"+entityDsc);
        }
    }
}
